/*
 * @(#)ArchTree.java   09/09/19
 * 
 * Copyright (C) 2009 Ecole des Mines d'Ales
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Contact: yulinz88@gmail.com
 */



package fr.ema.arch3d.gea.mainGUI.archExplorer;

import fr.ema.arch3d.model.architecture.configuration.ComponentClass;
import fr.ema.arch3d.model.architecture.configuration.Configuration;
import fr.ema.arch3d.model.architecture.configuration.ConnectorClass;
import fr.ema.arch3d.model.architecture.specification.ComponentRole;
import fr.ema.arch3d.model.architecture.specification.Connection;
import fr.ema.arch3d.model.architecture.specification.Specification;
import fr.ema.arch3d.ref.Fractal;

import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.NoSuchInterfaceException;

import java.util.ArrayList;
import java.util.List;

import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreeSelectionModel;

//~--- classes ----------------------------------------------------------------

/**
 * Class description
 *
 *
 * @version        1.0, 09/09/13
 * @author         Huaxi (Yulin) ZHANG
 */
public class ArchTree extends JTree {

    /**
     * Constructs ...
     *
     *
     * @param root
     */
    public ArchTree(TreeNode root) {
        super(root);
    }

    /**
     * Constructs ...
     *
     *
     * @param spec
     * @param config
     * @param container
     */
    public ArchTree(Specification spec, Configuration config, Component container) {

        DefaultMutableTreeNode specN = null, configN=null, assN=null;
        // define specification subtree
	if (spec!=null) {
	    specN = new DefaultMutableTreeNode("Specification", true);
	    DefaultMutableTreeNode cmps = new DefaultMutableTreeNode(
		    "Component_roles", true);
	    DefaultMutableTreeNode cnts = new DefaultMutableTreeNode(
		    "Connections", true);
	    for (int i = 0; i < spec.getCmpRoleList().size(); i++) {
		cmps.add(new DefaultMutableTreeNode(
			((ComponentRole) spec.getCmpRoleList().get(i)).getName()));
	    }
	    for (int i = 0; i < spec.getConnectionList().size(); i++) {
		cnts.add(new DefaultMutableTreeNode(
			((Connection) spec.getConnectionList().get(i)).getName()));
	    }
	    specN.add(cmps);
	    specN.add(cnts);
	}
	if (config != null) {

            // define configuration subtree
	    configN = new DefaultMutableTreeNode("Configuration", true);
            DefaultMutableTreeNode cmpc    = new DefaultMutableTreeNode("Component_classes", true);
            DefaultMutableTreeNode cntc    = new DefaultMutableTreeNode("Connector_classes", true);

            for (int i = 0; i < config.getCmpClasses().size(); i++) {
                cmpc.add(new DefaultMutableTreeNode(((ComponentClass) config.getCmpClasses().get(i)).getName()));
            }

            for (int i = 0; i < config.getConnectorClasses().size(); i++) {
                cntc.add(new DefaultMutableTreeNode(((ConnectorClass) config.getConnectorClasses().get(i)).getName()));
            }

            configN.add(cmpc);
            configN.add(cntc);
        }

        // define assembly subtree
        if (container!=null) {
	    assN = new DefaultMutableTreeNode("Assembly", true);
	    DefaultMutableTreeNode cmpa = new DefaultMutableTreeNode(
		    "Component_instances", true);
	    DefaultMutableTreeNode cnta = new DefaultMutableTreeNode(
		    "Connector_instances", true);
	    List cmpas = new ArrayList();
	    List ctras = new ArrayList();
	    try {
		Component[] cs = (Component[]) Fractal.getContentController(
			container).getFcSubComponents();

		for (int i = 0; i < cs.length; i++) {
		    Component c = cs[i];

		    if (Fractal.getElementtypeController(c).getElementType()
			    .equals("component")) {
			cmpas.add(cs[i]);
		    }

		    if (Fractal.getElementtypeController(
			    (org.objectweb.fractal.api.Component) c)
			    .getElementType().equals("connector")) {
			ctras.add(cs[i]);
		    }
		}
	    } catch (NoSuchInterfaceException e) {

		// TODO Auto-generated catch block
		e.printStackTrace();
	    }
	    for (int i = 0; i < cmpas.size(); i++) {
		try {
		    cmpa
			    .add(new DefaultMutableTreeNode(
				    (Fractal
					    .getNameController((org.objectweb.fractal.api.Component) ((List) cmpas)
						    .get(i)).getFcName())));
		} catch (NoSuchInterfaceException e) {

		    // TODO Auto-generated catch block
		    e.printStackTrace();
		}
	    }
	    for (int i = 0; i < ctras.size(); i++) {
		try {
		    cnta
			    .add(new DefaultMutableTreeNode(
				    (Fractal
					    .getNameController((org.objectweb.fractal.api.Component) ((List) ctras)
						    .get(i)).getFcName())));
		} catch (NoSuchInterfaceException e) {

		    // TODO Auto-generated catch block
		    e.printStackTrace();
		}
	    }
	    assN.add(cmpa);
	    assN.add(cnta);
	}
	try {
            UIManager.setLookAndFeel("com.birosoft.liquid.LiquidLookAndFeel");
        } catch (ClassNotFoundException e) {

            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {

            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {

            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedLookAndFeelException e) {

            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // define root
        DefaultMutableTreeNode arch = new DefaultMutableTreeNode("Architectures", true);

        if (specN!=null) {
	    arch.add(specN);
	}
	if (configN!=null) {
	    arch.add(configN);
	}
	if (assN!=null) {
	    arch.add(assN);
	}
	setModel(new DefaultTreeModel(arch));
        this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

        DefaultTreeCellRenderer myCellRenderer = new ArchTreeCellRender();

        this.setCellRenderer(myCellRenderer);
        this.setShowsRootHandles(true);
        SwingUtilities.updateComponentTreeUI(this);
    }
}
